'''
Created on 2009-11-18

@author: wangyongtao
'''
from google.appengine.ext import db
from google.appengine.api.labs import taskqueue
from google.appengine import runtime
from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app
import mokomodel
import moko
import math
import logging
import utility

class AdminPage(utility.BaseRequestHandler):
    _ACTION_MAP = {
                   'default':   'indexAction',
                   'album':     'albumAction',
                   'albums':     'albumsAction',
                   'models':     'modelsAction',
                   'addmodel':  'addmodelAction',
                   'model':     'modelAction',
                   'filter':     'filterAction',
                   'gallery':   'galleryAction',
                   'photosizer':'photosizerAction',
                   'setting':   'settingAction',
                   }
    _ACTION_POST_MAP = {
                   'default':   'indexPostAction',
                   'album':     'albumPostAction',
                   'addmodel':  'addmodelPostAction',
                   'albums':     'albumsPostAction',
                   'models':     'modelsPostAction',
                   'model':     'modelPostAction',
                   'gallery':   'galleryPostAction',
                   'photosizer':'photosizerPostAction',
                   'setting':   'settingPostAction',
                   }
    def get(self, target):
        actionName = AdminPage._ACTION_MAP['default']
        action = None
        if not target:
            action = getattr(self, actionName)
        else:
            t = target.lower()
            if t.find('/'):
                items = t.split('/')
                t = items[0]
            if t in AdminPage._ACTION_MAP:
                actionName = AdminPage._ACTION_MAP[t]
            action = getattr(self, actionName)
        if action:
            action(target)
            
    def post(self, target):
        actionName = AdminPage._ACTION_POST_MAP['default']
        action = None
        if not target:
            action = getattr(self, actionName)
        else:
            t = target.lower()
            if t.find('/'):
                items = t.split('/')
                t = items[0]
            if t in AdminPage._ACTION_POST_MAP:
                actionName = AdminPage._ACTION_POST_MAP[t]
            action = getattr(self, actionName)
        if action:
            action(target)
            
    def albumAction(self, target=None):
        items = target.split('/')
        if len(items) == 1:
            self.redirect('/admin/albums', True)
        modelname = items[1]
        model = mokomodel.model.get_model(modelname)
        if not model:
            logging.error('the input model with name (%s) does not exist.'%modelname)
            self.error(403)
        target = self.request.get('target', 'all')
        targets = ('all', 'selected', 'iphone', 'excluded', 'downloaded')
        operation = self.request.get('with', 1)
        q = db.Query(mokomodel.album).filter('model =', model)
        if target in targets:
            if target != 'all':
                q.filter('%s ='%target, bool(int(operation)))
        albums = q.fetch(1000, 0)
        self.generate('admin.album.html', { 'model': model,
                                      'albums': albums,
                                      'pages': range(1, 2),
                                      'page': 1,})
        
    def albumsAction(self, target=None):
        albums = []
        count = self.request.get('count', None)
        if not count:
            count = 20
        else:
            count =int(count)
        try:
            list = mokomodel.cronlog.get_non_verified_albums(count)
            if list:
                for a in list:
                    if a.count_photo > a.get_photo_count():
                        albums.append(a)
        except runtime.DeadlineExceededError,e:
            logging.error('met deadline error:%s'%e.message)
            
        self.generate('admin.album.html', {'albums':albums})
    
    def settingAction(self, target=None):
        return False
    
    def filterAction(self, target=None):
        target = self.request.get('target', 'album')
        key = self.request.get('key',None)
        if target == 'album':
            taskqueue.add(url='/task/filteralbum', params={'album':key, 'ignore':True}, method='GET')
        elif target== 'model':
            taskqueue.add(url='/task/filtermodel', params={'model':key, 'ignore':True}, method='GET')
    
    def photosizerAction(self, target=None):
        self.generate('admin.photosize.html', {})
    
    def photosizerPostAction(self, target=None):
        url = None
        width = None
        height = None
        photos = {}
        for k,v in self.request.params.items():
            if k == 'field_url':
                url = v
            elif k == 'field_width':
                width = v
            elif k == 'field_height':
                height = v
            if url and width and height:
                photos[url] = {'url': url, 'width': width, 'height':height}
                url = None
                width = None
                height = None
        logging.info('get items:%d'%len(photos.keys()))
        logs = []
        for k,v in photos.items():
            photo = mokomodel.photo.get_photo_by_url(k)
            if photo:
                w = int(v['width'])
                h = int(v['height'])
                if w and w> 0 and h and h>0:
                    photo.width = w
                    photo.height = h
                    photo.put()
                    log = 'Update photo size successful[url:%(url)s width:%(w)d height:%(h)d]'%{'url':k, 'w':w, 'h':h}
                    logs.append(log)
            else:
                log = 'Did not find photo:%s'%k
                logs.append(log)
        self.generate('admin.photosize.html', {'logs':logs,})
    
    def addmodelAction(self, target=None):
        self.generate('admin.addmodel.html', {
                      'application_name' : 'MOKO Top Girl List',
                      'model': None,
                      })
        
    def addmodelPostAction(self, target=None):
        btn = self.request.get("submit")
        msg = None
        if btn.lower()== "search":
            username = self.request.get('username')
            model = None        
            if username is not None:
                logging.info("add model:%s"%username)
                model = mokomodel.model.get_model(username)
                if model is None:
                    msg = "Did's find model with username:%s"%username
                    logging.info(msg)
                else:
                    taskqueue.add(url='/task/model', params={'model': username}, method='GET')
        else:
            models = dict()
            for k,v in self.request.params.items():
                splits = k.split('_')
                if len(splits) == 2:
                    modelname = splits[1].lower()
                    key = splits[0].lower()
                    if not models.has_key(splits[1]):
                        models[modelname] = {'model': True, 'mtg': False, 'iphone': False, 'iphonefree':False}
                    models[modelname][key] = True

            for item in models.keys():
                m = mokomodel.model.get_model(item)
                if m:
                    m.mtg = models[item]['mtg']
                    if m.mtg:
                        m.gender = False
                    m.iphone = models[item]['iphone']
                    m.iphonefree = models[item]['iphonefree']
                    m.put()
                    model = m
            msg = "update model successed"
        self.generate('admin.addmodel.html', {
                      'application_name' : 'MOKO Top Girl List',
                      'model': model,
                      'msg': msg,
                      })   
        
    def modelsAction(self, target=None):
        targets = ('gender', 'mtg', 'iphone')
        target = self.request.get('target', 'gender')
        operation = self.request.get('with', 0)
        page = self.pageHandler()
        offset = (page-1)*moko.MAX_PER_PAGE
        if target in targets:
            q = db.Query(mokomodel.model)
            if target == 'gender':
                q.filter('gender =', bool(int(operation)))
            elif target == 'mtg':
                q.filter('gender =', False).filter('mtg =', bool(int(operation)))
            elif target == 'iphone':
                q.filter('gender =', False).filter('mtg =', True).filter('iphone =', bool(int(operation)))
            count = q.count(1000)
            models = q.order('-visitcount').fetch(moko.MAX_PER_PAGE, offset)
        else:
            logging.error('target parameter is out of range:%s'%target)
            
        pages = int(math.ceil(count/float(moko.MAX_PER_PAGE)))
        prev = False
        if page > 1:
            prev = page -1
        next = False
        if page < pages:
            next = page + 1
        logging.info('next:%s'%next)
        
        self.generate('admin.models.html', {
                      'application_name' : 'MOKO Top Girl List',
                      'models': models,
                      'pages': range(1, pages+1),
                      'page': page,
                      'count': count,
                      'prev': prev,
                      'next': next,
                      'target':target,
                      'operation': operation,
                })
    def modelsPostAction(self, target=None):
        models = dict()
        for k,v in self.request.params.items():
            splits = k.split('_')
            if len(splits) == 2:
                modelname = splits[1].lower()
                key = splits[0].lower()
                if not models.has_key(splits[1]):
                    models[modelname] = {'model': True, 'mtg': False, 'iphone': False, 'iphonefree':False}
                models[modelname][key] = True

        for model in models.keys():
            m = mokomodel.model.get_model(model)
            if m:
                m.mtg = models[model]['mtg']
                if m.mtg:
                    m.gender = False
                m.iphone = models[model]['iphone']
                m.iphonefree = models[model]['iphonefree']
                m.put()
        self.modelsAction()
        
    def albumPostAction(self, target=None):
        albums = dict()
        for k,v in self.request.params.items():
            splits = k.split('_')
            if len(splits) >= 2:
                albumkey = splits[1]
                if len(splits) > 2:
                    end = len(splits)
                    albumkey = '_'.join(splits[1:end])
                key = splits[0].lower()
                if not albums.has_key(albumkey):
                    albums[albumkey] = {'iphone': False, 'selected':False}
                albums[albumkey][key] = True

        
        for key in albums.keys():
            item = mokomodel.album.get(key)
            if item:
                item.iphone = albums[key]['iphone']
                item.put()
        self.albumAction(target)
        
    def modelAction(self, target):
        m = None
        if target.find('/'):
            items = target.split('/')
            modelname = items[1]
            m = mokomodel.model.get_model(modelname)
        if m:
            avatars = m.get_avatar_photos()
            self.generate('admin.topgirl.html', {'model': m, 'avatars':avatars,})
        else:
            self.generate('admin.topgirl.html', {'error': True,})
    
    def modelPostAction(self, target):
        m = None
        if target.find('/'):
            items = target.split('/')
            modelname = items[1]
            m = mokomodel.model.get_model(modelname)
        if m:
            cats = []
            for k,v in self.request.params.items():
                logging.info('key:%s'%k)
                logging.info('value:%s'%v)
                if k == 'category':
                    if v.strip() != '':
                        cats.append(v.strip())
                elif k == 'name_cn':
                    m.name_cn = v
                elif k == 'name_en':
                    m.name_en = v
                elif k == 'avatar':
                    photo = mokomodel.photo.get(v)
                    if photo:
                        m.avatar = photo.url
                        logging.info('updated avatar')
                    else:
                        logging.info('not found photo with the key')
            m.category = cats
            m.checked = True
            m.put()
            self.modelAction(target)
            
    def indexAction(self, target=None):
        logging.info('Admin Index action')
        self.generate('admin.index.html')
          
application = webapp.WSGIApplication([
            (r'/admin/(.*)', AdminPage),
            ], debug=utility.DEBUG)

def main():
    run_wsgi_app(application)

if __name__ == "__main__":
    main()